import json
import re

from QQLoginTool.QQtool import OAuthQQ
from django import http
from django.conf import settings
from django.contrib.auth import login
from django.http import JsonResponse
from django.shortcuts import render, redirect

# Create your views here.
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from apps.oauth import sinaweibopy3
from apps.oauth.models import OAuthQQUser, OAuthSinaUser
from apps.users.models import User
from utils.response_code import RETCODE
from utils.secret import SecretOauth


class QQLoginView(View):
    def get(self, request):
        # 1.导包 qq登录工具
        from QQLoginTool.QQtool import OAuthQQ

        # 2.实例化对象--->认证的参数
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
            state=None
        )

        # 3.获取qq登录地址 返回给前端 JsonResponse
        login_url = oauth.get_qq_url()

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})


# 判断是否绑定openid
def is_bind_openid(openid, request):
    # 判断 openid 在不在 QQ等录表OAuthQQUser
    try:
        qq_user = OAuthQQUser.objects.get(openid=openid)
    except OAuthQQUser.DoesNotExist:
        # 不存在--跳转到 绑定页面
        context = {'openid': openid}
        response = render(request, 'oauth_callback.html', context)
    else:
        # 存在
        user = qq_user.user
        # 1.保持登录装填
        login(request, user)
        # 2. cookie保存用户名
        response = redirect(reverse('contents:index'))
        response.set_cookie('username', user.username, max_age=14 * 2 * 24 * 3600)

        # 3. 重定向首页
    return response
# http://www.meiduo.site:8000/oauth_callback?code=D185854B840E6F9C3038199FE7735995&state=None
class QQOauthCallbackView(View):
    def get(self, request):
        # 1.code request.GET.get
        code = request.GET.get('code')

        # uri > url
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)

        # 2. code-->acess_token
        token = oauth.get_access_token(code)

        # 3. acesss_token =--->openid
        openid = oauth.get_open_id(token)
        # return http.HttpResponse(openid)

        # 4. 判断是否绑定openid
        response = is_bind_openid(openid, request)
        return response
    def post(self,request):
        #接收参数
        mobile = request.POST.get('mobile')
        pwd = request.POST.get('password')
        sms_code = request.POST.get('sms_code')
        openid = request.POST.get('openid')
        #正则校验
        # 判断参数是否齐全
        if not all([mobile, pwd, sms_code]):
            return http.HttpResponseForbidden('缺少必传参数')
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号码')
        # 判断密码是否合格
        if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):
            return http.HttpResponseForbidden('请输入8-20位的密码')
        # 判断短信验证码是否一致
        redis_conn = get_redis_connection('sms_code')
        print(redis_conn)
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        if sms_code_server is None:
            return render(request, 'oauth_callback.html', {'sms_code_errmsg': '无效的短信验证码'})
        if sms_code != sms_code_server.decode():
            return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'})
        if not openid:
            return render(request,'oauth_callback.html', {'openid_errmsg': '无效的openid'})
        #判断手机号是否存在
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            user = User.objects.create_user(username=mobile,password=pwd,mobile=mobile)
        else:
            if not user.check_password(pwd):
                return render(request,'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})
        #存在直接返回到主页，不存在重新创建一个，同时绑定openid和user
        OAuthQQUser.objects.create(user=user,openid=openid)
        #返回首页,保持登陆状态
        login(request,user)
        response = redirect(reverse('contents:index'))
        response.set_cookie('username', user.username, max_age=14 * 2 * 24 * 3600)
        # 5.返回首页

        # 登陆成功，合并购物车
        from apps.carts.utils import merge_cart_cookie_to_redis
        merge_cart_cookie_to_redis(request, response)

        return response
        #

class WeiboLoginView(View):
    def get(self,request):
        next = request.GET.get('next')

        client = sinaweibopy3.APIClient(
            # app_key： app_key值
            app_key=settings.APP_KEY,
            # app_secret：app_secret 值
            app_secret=settings.APP_SECRET,
            # redirect_uri ： 回调地址
            redirect_uri=settings.REDIRECT_URL
        )
        login_url = client.get_authorize_url()
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})
class SinaCallbackView(View):
    def get(self,request):
        code = request.GET.get('code')
        #创建工具对象
        client = sinaweibopy3.APIClient(
            # app_key： app_key值
            app_key=settings.APP_KEY,
            # app_secret：app_secret 值
            app_secret=settings.APP_SECRET,
            # redirect_uri ： 回调地址
            redirect_uri=settings.REDIRECT_URL
        )
        #根据code获取access_token和uid
        result = client.request_access_token(code)
        access_token = result.access_token
        uid = result.uid
        # print(uid)
        try:

            sina_user = OAuthSinaUser.objects.get(uid=uid)

        except OAuthSinaUser.DoesNotExist:
            # 不存在--跳转到 绑定页面
            secret_openid = SecretOauth().dumps({'uid': uid})
            context = {'uid': secret_openid}

            return render(request, 'sina_callback.html', context)
        # 存在
        user = sina_user.user
        # print(user)
        # 1.保持登录装填
        login(request, user)
        # 2. cookie保存用户名
        response = redirect(reverse('contents:index'))
        response.set_cookie('username', user.username, max_age=14 * 2 * 24 * 3600)

        # 3. 重定向首页
        return response

class SinaUserView(View):
    def post(self,request):
        # 接收参数
        json_dict = json.loads(request.body.decode())
        mobile = json_dict.get('mobile')
        password = json_dict.get('password')
        sms_code =json_dict.get('sms_code')
        uid = json_dict.get('uid')
        uid = SecretOauth().loads(uid).get('uid')
        if not uid:
            return render(request, 'sina_callback.html', {'uid_errmsg': '无效的uid'})
        # 正则校验
        # 判断参数是否齐全
        if not all([mobile, password, sms_code]):
            return http.HttpResponseForbidden('缺少必传参数')
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号码')
        # 判断密码是否合格
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20位的密码')
        # 判断短信验证码是否一致
        redis_conn = get_redis_connection('sms_code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        if sms_code_server is None:
            return render(request, 'sina_callback.html', {'sms_code_errmsg': '无效的短信验证码'})
        if sms_code != sms_code_server.decode():
            return render(request, 'sina_callback.html', {'sms_code_errmsg': '输入短信验证码有误'})

        # 判断手机号是否存在
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)
        else:
            if not user.check_password(password):
                return render(request, 'sina_callback.html', {'account_errmsg': '用户名或密码错误'})
        # 存在直接返回到主页，不存在重新创建一个，同时绑定openid和user
        OAuthSinaUser.objects.create(user=user, uid=uid)
        # 返回首页,保持登陆状态
        login(request, user)
        response =http.JsonResponse({'status':5000})
        response.set_cookie('username', user.username, max_age=14 * 2 * 24 * 3600)
        # 5.返回首页
        return response


